package com.usian.wemedia.service.impl;

import com.alibaba.fastjson.JSON;
import com.alibaba.fastjson.JSONArray;
import com.alibaba.fastjson.JSONObject;
import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.baomidou.mybatisplus.core.toolkit.Wrappers;
import com.usian.common.constants.WemediaContans;
import com.usian.model.base.BaseServiceImpl;
import com.usian.model.common.dtos.ResponseResult;
import com.usian.model.common.enums.AppHttpCodeEnum;
import com.usian.model.media.dtos.WmNewsDto;
import com.usian.model.media.dtos.WmNewsPageReqDto;
import com.usian.model.media.pojos.WmMaterial;
import com.usian.model.media.pojos.WmNews;
import com.usian.model.media.pojos.WmNewsMaterial;
import com.usian.utils.threadlocal.WmThreadLocalUtils;
import com.usian.wemedia.mapper.WmMaterialMapper;
import com.usian.wemedia.mapper.WmNewsMapper;
import com.usian.wemedia.mapper.WmNewsMaterialMapper;
import com.usian.wemedia.service.WmNewsService;
import org.apache.commons.beanutils.BeanUtils;
import org.apache.commons.lang3.StringUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

import java.lang.reflect.InvocationTargetException;
import java.util.*;
import java.util.function.Function;
import java.util.function.Predicate;
import java.util.stream.Collectors;

@Transactional
@Service
public class WmNewsServiceImpl extends BaseServiceImpl<WmNewsMapper, WmNews> implements WmNewsService {
    @Value("${fdfs.url}")
    private String baseUrl;

    @Autowired
    private WmNewsMaterialMapper newsMaterialMapper;
    @Autowired
    private WmMaterialMapper materialMapper;

    @Override
    public ResponseResult findAll(WmNewsPageReqDto dto) {
        //参数检查
        if (dto == null) return paramError;
        LambdaQueryWrapper<WmNews> wrapper = new LambdaQueryWrapper<>();
        //状态
        if (dto.getStatus() != null)
            wrapper.eq(WmNews::getStatus, dto.getStatus());
        //标题
        if (StringUtils.isNotBlank(dto.getKeyword()))
            wrapper.like(WmNews::getTitle, dto.getKeyword());
        //频道
        if (dto.getChannelId() != null)
            wrapper.eq(WmNews::getChannelId, dto.getChannelId());
        //获取ap_userId
        Integer userId = WmThreadLocalUtils.getUserId();
        if (userId == null) return needLogin;
        wrapper.eq(WmNews::getUserId, userId);
        //日期范围
        if (dto.getBeginPubDate() != null && dto.getEndPubDate() != null)
            wrapper.between(WmNews::getPublishTime, dto.getBeginPubDate(), dto.getEndPubDate());
//        if (dto.getNowTime()==null) dto.setNowTime(new Date());
//        wrapper.lt(WmNews::getPublishTime,dto.getNowTime());
        wrapper.orderByDesc(WmNews::getCreatedTime);
        ResponseResult pageResult = getPageResult(dto, wrapper);
        pageResult.setHost(baseUrl);
        return pageResult;
    }

    private void resetCovers(List<String>covers,WmNews wmNews){
        StringBuffer buffer = new StringBuffer();
        covers.forEach(s -> buffer.append(s.contains("http") ? s.replace(baseUrl, "") : s).append(","));
        String urls = buffer.toString().substring(0, buffer.toString().length() - 1);
        wmNews.setImages(urls);
    }

    /**
     * 文章发布
     *
     * @param dto      前端传的新闻对象
     * @param isSubmit 是否为提交 1 为提交 0为草稿
     * @return
     */
    @Override
    public ResponseResult saveNews(WmNewsDto dto, Short isSubmit) {
        //判断前端必传参数是否为空
        if (dto == null || StringUtils.isBlank(dto.getContent())) {
            return paramError;
        }
        //保存或更新文章
        WmNews wmNews = new WmNews();
        try {
            BeanUtils.copyProperties(wmNews, dto);
        } catch (IllegalAccessException e) {
            e.printStackTrace();
        } catch (InvocationTargetException e) {
            e.printStackTrace();
        }
        if (WemediaContans.WM_NEWS_TYPE_AUTO.equals(dto.getType())) {
            wmNews.setType(null);
        }
        if (dto.getImages() != null && dto.getImages().size() > 0) {
            resetCovers(dto.getImages(),wmNews);
        }
        wmNews.setUserId(WmThreadLocalUtils.getUserId());
        if (wmNews.getCreatedTime() == null) wmNews.setCreatedTime(new Date());
        wmNews.setStatus(isSubmit);
        wmNews.setEnable((short) 0);
        if (wmNews.getId() == null) {
            save(wmNews);
        } else {
            updateById(wmNews);
            LambdaQueryWrapper<WmNewsMaterial> wrapper = new LambdaQueryWrapper<>();
            wrapper.eq(WmNewsMaterial::getNewsId, wmNews.getId());
            newsMaterialMapper.delete(wrapper);
            updateById(wmNews);
        }
        //处理中间表，插入数据
        List<String> urlList = getUrlList(wmNews);  //内容图片集合
        List<String> covers = dto.getImages();
        //保存文章内容中的图片和新闻的关系数据
        if (isSubmit == WmNews.Status.SUBMIT.getCode()){
            saveCP(urlList,wmNews,WemediaContans.WM_CONTENT_REFERENCE);
            //前端没有指定几图模式时，默认自动-1，不用封面图，从内容中提取
            if (dto.getType().equals(WemediaContans.WM_NEWS_TYPE_AUTO)){
                if (urlList.size()==1 || urlList.size()==2){
                    //单图模式
                    wmNews.setType(WemediaContans.WM_NEWS_SINGLE_IMAGE);
                    covers= Arrays.asList(urlList.get(0));  //封面图片集合
                }else if (urlList.size()>2){
                    //多图模式
                    wmNews.setType(WemediaContans.WM_NEWS_MANY_IMAGE);
                    covers=urlList.stream().limit(3).collect(Collectors.toList());
                }else {
                     wmNews.setType(WemediaContans.WM_NEWS_NONE_IMAGE);
                     if (covers !=null) covers.clear();
                }
                if (covers !=null && covers.size()!=0)resetCovers(covers,wmNews);
                updateById(wmNews);
                saveCP(covers,wmNews,WemediaContans.WM_COVER_REFERENCE);
            }
        }

        return paramSuccess;
    }

    @Override
    public ResponseResult findWmNewsById(Integer id) {
        if (id==null)return paramError;
        WmNews wmNews = getById(id);
        if (wmNews==null) return notExits;
        ResponseResult result = ResponseResult.okResult(wmNews);
        result.setHost(baseUrl);
        return result;
    }

    @Override
    public ResponseResult delNews(Integer id) {
        //必传参数不能为空
        if (id==null) return paramError;
        //判断新闻是否存在
        WmNews wmNews = getById(id);
        if (wmNews==null) return notExits;
        //判断文章状态  status==9已提交  enable == 1已上架
        if (wmNews.getStatus().equals(WmNews.Status.PUBLISHED.getCode())&&
            wmNews.getEnable().equals(WemediaContans.WM_NEWS_ENABLE_UP)){
            return ResponseResult.errorResult(AppHttpCodeEnum.NO_OPERATOR_AUTH,"上架或已提交的文章，不能删除");
        }
        //删除中间表
        LambdaQueryWrapper<WmNewsMaterial> wrapper = Wrappers.<WmNewsMaterial>lambdaQuery().eq(WmNewsMaterial::getNewsId, id);
        newsMaterialMapper.delete(wrapper);
        //删除新闻表
        removeById(id);
        return paramSuccess;
    }

    @Override
    public WmNews findById(Integer id) {
        if (id==null) return null;
        return getById(id);
    }

    @Override
    public ResponseResult updateWmNews(WmNews wmNews) {
        if (wmNews==null) return paramError;
        updateById(wmNews);
        return paramSuccess;
    }

    private void saveCP(List<String> urlList,WmNews wmNews,Short type){
        if (urlList.size() != 0){
            List<WmMaterial> materialList = materialMapper.selectList(Wrappers.<WmMaterial>lambdaQuery().in(WmMaterial::getUrl, urlList));
            List<Integer> idList = materialList.stream().map(m -> m.getId()).collect(Collectors.toList());
            newsMaterialMapper.saveRelationsByContent(idList,wmNews.getId(),type);
        }
    }

    private List<String> getUrlList(WmNews wmNews) {
        String content = wmNews.getContent();
//        List<String>list=new ArrayList<>();
//        //java写法
//        JSONArray array = JSON.parseArray(content);
//        array.forEach(o->{
//            JSONObject object = JSON.parseObject(o.toString());
//            if (object.get("type").equals(WemediaContans.WM_NEWS_TYPE_IMAGE)){
//                String value = (String) object.get("value");
//                value=value.replace(baseUrl,"");
//                list.add(value);
//            }
//        });
//        //map写法
//        List<Map> maps = JSON.parseArray(content, Map.class);
//        maps.forEach(m->{
//            if (m.get("type").equals(WemediaContans.WM_NEWS_TYPE_IMAGE)){
//                String url = (String) m.get("value");
//                url=url.replace(baseUrl,"");
//                list.add(url);
//            }
//        });
        //stream写法
        return JSON.parseArray(content, Map.class).stream().filter(map -> map.get("type").equals(WemediaContans.WM_NEWS_TYPE_IMAGE)).map(map -> ((String) map.get("value")).replace(baseUrl, "")).collect(Collectors.toList());
    }
}
